package com.whjz.common;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.whjz.utils.ReflectUtil;
import com.whjz.utils.Utils;

import java.util.Arrays;

public class ISetUtil {
    /**
     * 转换为相同字段的对象
     * @param sourceObj 源对象
     * @param toCls 目标类
     * @return 目标对象
     */
    public static <T> T toEqual(Object sourceObj, Class<T> toCls) {
        try {
            return JSON.parseObject(Utils.MAPPER.writeValueAsString(sourceObj), toCls);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 合并入对象,相同字段不为null值进行覆盖(null值不会覆盖过去)
     * 会遍历对象内的成员变量,但不会对每个成员变量递归进行处理
     * @param sourceObj 源对象
     * @param toCls 目标类
     * @param targetObj 目标对象
     */
    public static <T> void merge(Object sourceObj, Class<T> toCls, T targetObj) {
        try {
            T obj = JSON.parseObject(Utils.MAPPER.writeValueAsString(sourceObj), toCls);
            Arrays.stream(toCls.getDeclaredFields()).forEach(field -> {
                try {
                    Object value = ReflectUtil.getField(field, obj);
                    if (value != null) {
                        ReflectUtil.setField(field, targetObj, value);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 合并入对象,相同字段不为null值进行覆盖(null值不会覆盖过去),
     * 需要目标对象对应字段值为null才覆盖
     * 会遍历对象内的成员变量,但不会对每个成员变量递归进行处理
     * @param sourceObj 源对象
     * @param toCls 目标类
     * @param targetObj 目标对象
     */
    public static <T> void mergeNull(Object sourceObj, Class<T> toCls, T targetObj) {
        try {
            T obj = JSON.parseObject(Utils.MAPPER.writeValueAsString(sourceObj), toCls);
            Arrays.stream(toCls.getDeclaredFields()).forEach(field -> {
                try {
                    Object value = ReflectUtil.getField(field, obj);
                    Object targetValue = ReflectUtil.getField(field, targetObj);
                    if (value != null && targetValue == null) {
                        ReflectUtil.setField(field, targetObj, value);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e.getMessage());
        }
    }
}
